/*
 * Copyright @ 2010 Radomir Mladenovic and BugsIO Solutions
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 *       
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.gjutil.caching.provider;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.LogAndContinueErrorHandler;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceException;
import com.google.appengine.api.memcache.MemcacheServiceFactory;


public class GAEMemcacheProvider extends AbstractCacheProvider {
	private static final Logger log = Logger.getLogger(GAEMemcacheProvider.class.getName());
	
	private MemcacheService memcache;
	private MemcacheService.SetPolicy setPolicy = MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT;
	
	public GAEMemcacheProvider() {
		this("GAE Caching Interceptor");
	}
	
	public GAEMemcacheProvider(String name) {
		memcache = MemcacheServiceFactory.getMemcacheService();
		memcache.setNamespace(name);
		setName(name);
		
		// added handler because I had some strange errors ("entity too large" although it was not) 
		// with dev server but not seen since
		memcache.setErrorHandler(new LogAndContinueErrorHandler(Level.FINE) {

			@Override
			public void handleServiceError(MemcacheServiceException thrown) {
				
				log.log(Level.SEVERE, "Memcache service error!", thrown);
				
				super.handleServiceError(thrown);
			}
		});
	}
		
	public Object getFromCache(Object key) {
		return memcache.get(key);
	}

	public void putInCache(Object key, Object value, int expirationSeconds, Boolean setAlways) {
		if (value == null && !isCacheNull())
			return;

		Expiration expires = null;
		if (expirationSeconds > 0)
			expires = Expiration.byDeltaSeconds(expirationSeconds);
		else if (getExpirationSeconds() > 0)
			expires = Expiration.byDeltaSeconds(getExpirationSeconds());

		MemcacheService.SetPolicy setPolicy = this.setPolicy;
		if (setAlways != null && setAlways.booleanValue())
			setPolicy = MemcacheService.SetPolicy.SET_ALWAYS;

		memcache.put(key, value, expires, setPolicy);		
	}

	/**
	 * Does nothing for GAE Memcache.
	 */
	public void cleanup() {
	}

	public MemcacheService.SetPolicy getSetPolicy() {
		return setPolicy;
	}

	public void setSetPolicy(MemcacheService.SetPolicy setPolicy) {
		this.setPolicy = setPolicy;
	}
	
}
